<script lang="ts" setup>
import type { CatalogListData } from './index';

import { computed, onBeforeMount, reactive, ref } from 'vue';

import { Page } from '@vben/common-ui';
import {
  ElDelete,
  ElDocumentAdd,
  ElDownload,
  ElPriceTag,
  ElSearch,
  ElUploadFilled,
  ElView,
} from '@vben/icons';

import { StorageManager } from '@vben-core/shared/cache';

import {
  ElAvatar,
  ElButton,
  ElCard,
  ElDivider,
  ElEmpty,
  ElInput,
  ElMessage,
  ElPagination,
  ElSkeleton,
  ElSkeletonItem,
  ElTooltip,
} from 'element-plus';

import { fileApi, publicResourcesApi, userApi } from '#/api';
import { $t } from '#/locales';

import {
  avatar,
  folderIcon,
  geojsonIcon,
  otherIcon,
  pdfIcon,
  shpIcon,
  tupianIcon,
  zipIcon,
} from './assets';
import {
  AddTagDialog,
  MvtPreviewDialog,
  PublishDialog,
  RasterPreviewDialog,
} from './components';

const AppOptions = import.meta.env;
const storageManager = new StorageManager({
  prefix: '',
  storageType: 'sessionStorage',
});

const isLoading = ref(true);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(100);
const keyword = ref('');
const selectedTag = ref('矢量服务');
const isMvtPreviewDialogShow = ref(false);
const isRasterPreviewDialogShow = ref(false);

const email = `${AppOptions.VITE_ADMIN_EMAIL}`;
const userId = storageManager.getItem('userId');
const isAdmini = ref(false);
const isAddTagShow = ref(false);
const realSelectedFileData = ref<any>(null);
const currentSelectedFile = ref<CatalogListData | null>(null);
const catalogList = reactive({
  data: [] as CatalogListData[],
});
const adminInfo = ref(
  {} as {
    avatar: string;
    email: string;
    institution: string;
    userName: string;
  },
);

const imageSrc = (type: string) => {
  switch (type) {
    case 'folder': {
      return folderIcon;
    }
    case 'geojson':
    case 'json': {
      return geojsonIcon;
    }
    case 'gif': {
      return tupianIcon;
    }
    case 'jpg': {
      return tupianIcon;
    }
    case 'pdf': {
      return pdfIcon;
    }
    case 'png': {
      return tupianIcon;
    }
    case 'shp': {
      return shpIcon;
    }
    case 'zip': {
      return zipIcon;
    }
    default: {
      return otherIcon;
    }
  }
};
const isAdmin = () => {
  if (storageManager.getItem('email') === email) isAdmini.value = true;
};
const publishDialog = ref(false);
const refreshPublicResources = async () => {
  // 判断请求的类型
  const isVectorService = selectedTag.value === '矢量服务';
  const fetchFunction = isVectorService
    ? publicResourcesApi.getVecList
    : publicResourcesApi.getRasList;

  // 发起请求
  const response = await fetchFunction(
    pageSize.value,
    currentPage.value,
    keyword.value,
  );

  // 更新数据
  catalogList.data = response.body;
  total.value = response.count;
  // 设置加载状态为完成
  isLoading.value = false;
};
function selectTag(tag: string) {
  selectedTag.value = tag;
  refreshPublicResources();
}
const selectedFileType = ref<null | string>(null);

const popconfirmVisible = ref(false);
const importServiceData = async (file: any) => {
  const apiMethod =
    selectedTag.value === '矢量服务'
      ? publicResourcesApi.importVec2Resources
      : publicResourcesApi.importRas2Resources;
  await apiMethod(userId as string, file.id);

  ElMessage({
    type: 'success',
    message: '导入矢量资服务成功！',
  });

  refreshPublicResources();
};

const handleConfirm = (file: any) => {
  importServiceData(file);
  popconfirmVisible.value = false;
};
const handleCloseDialog = () => {
  isAddTagShow.value = false;
};
const tagFileId = ref('');
const tagFileName = ref('');
const addTags = (fileid: string, filename: string) => {
  isAddTagShow.value = true;
  tagFileId.value = fileid;
  tagFileName.value = filename;
};

const filteredFiles = computed(() => {
  if (selectedFileType.value) {
    return catalogList.data.filter(
      (file) => file.type === selectedFileType.value,
    );
  }
  return catalogList.data;
});

const getAdminInfo = async () => {
  const res = await userApi.getUserInfoByEmail(AppOptions.VITE_ADMIN_EMAIL);
  adminInfo.value = res;
};

const showPublishDialog = (id: string, name: string, type: string) => {
  publishDialog.value = true;
  realSelectedFileData.value = computed(() => {
    return {
      id,
      label: name,
      type,
      catalogId: storageManager.getItem('currentCatalogId'),
    } as any;
  });
};
const previewData = (file: CatalogListData) => {
  if (file.type === 'geojson' || file.type === 'shp') {
    currentSelectedFile.value = file;
    isMvtPreviewDialogShow.value = true;
  } else if (file.type === 'image') {
    currentSelectedFile.value = file;
    isRasterPreviewDialogShow.value = true;
  }
};
const handleSizeChange = (_val: number) => {};
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  refreshPublicResources();
};

// 删除文件 file
const performDeleteFile = async (fileId: string) => {
  await publicResourcesApi.deleteService(fileId);
  refreshPublicResources();
};

const deletePublic = async (fileId: string) => {
  await performDeleteFile(fileId);
  ElMessage.success($t('page.resources.deleteFileSuccessMessage'));
};

const getResourceInfo = async (file: CatalogListData) => {
  try {
    currentSelectedFile.value = file;
  } catch (error) {
    console.error(error);
  }
};
const handleClosePreviewDialog = () => {
  isMvtPreviewDialogShow.value = false;
};
const handleClosePreviewDialogR = () => {
  isRasterPreviewDialogShow.value = false;
};
// 下载
const downloadFile = (fileId: string, fileUrl: string) => {
  const fileName = fileUrl.slice(Math.max(0, fileUrl.lastIndexOf('/') + 1));
  fileApi
    .downloadFile(fileId)
    .then((response) => {
      const blob = new Blob([response]);
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = fileName;
      a.click();
      URL.revokeObjectURL(url);
    })
    .catch((error) => {
      console.error('文件下载失败:', error);
    });
};

onBeforeMount(async () => {
  isLoading.value = true;
  isAdmin();
  refreshPublicResources();

  await getAdminInfo();
});
</script>

<template>
  <Page
    oncontextmenu="return false"
    onselectstart="return false"
    title=""
    auto-content-height
    class="flex h-full flex-col"
  >
    <template #title>
      <div class="flex">
        <div
          class="mt-2 flex w-1/4 min-w-[220px] flex-shrink-0 flex-nowrap gap-6 whitespace-nowrap"
        >
          <span
            v-for="tag in ['矢量服务', '栅格服务']"
            :key="tag"
            @click="selectTag(tag)"
            class="cursor-pointer rounded-full px-4 py-1 text-sm transition-all"
            :class="
              selectedTag === tag
                ? 'bg-black text-white'
                : 'bg-gray-100 text-gray-700'
            "
          >
            {{ tag }}
          </span>
        </div>
        <ElInput
          v-model="keyword"
          size="large"
          :placeholder="$t('scenes.searchScene')"
          clearable
        >
          <template #append>
            <ElButton :icon="ElSearch" @click="refreshPublicResources" />
          </template>
        </ElInput>
      </div>
    </template>

    <div class="flex h-full w-full">
      <div class="w-full overflow-y-auto bg-white p-4 dark:bg-black">
        <!-- 骨架屏 (Skeleton) -->
        <div
          v-if="isLoading"
          class="grid gap-2 md:grid-cols-1 lg:grid-cols-1 xl:grid-cols-2"
        >
          <ElCard v-for="n in 10" :key="n" shadow="hover" class="p-2 shadow-lg">
            <ElSkeleton animated>
              <template #template>
                <div class="flex justify-between">
                  <div class="flex w-full flex-col space-y-2">
                    <ElSkeletonItem
                      variant="text"
                      style="width: 60%; height: 16px"
                    />
                    <div class="flex items-center space-x-2">
                      <ElSkeletonItem
                        variant="image"
                        style="width: 32px; height: 32px"
                      />
                      <ElSkeletonItem
                        variant="text"
                        style="width: 20%; height: 14px"
                      />
                      <ElSkeletonItem
                        variant="text"
                        style="width: 30%; height: 14px"
                      />
                    </div>
                  </div>
                </div>

                <div class="mt-5 flex justify-between">
                  <div class="flex items-center space-x-2">
                    <ElSkeletonItem
                      variant="circle"
                      style="width: 30px; height: 30px"
                    />
                    <ElSkeletonItem
                      variant="text"
                      style="width: 150px; height: 14px"
                    />
                  </div>
                  <div class="flex space-x-2">
                    <ElSkeletonItem
                      variant="circle"
                      style="width: 30px; height: 30px"
                    />
                    <ElSkeletonItem
                      variant="circle"
                      style="width: 30px; height: 30px"
                    />
                    <ElSkeletonItem
                      variant="circle"
                      style="width: 30px; height: 30px"
                    />
                    <ElSkeletonItem
                      variant="circle"
                      style="width: 30px; height: 30px"
                    />
                  </div>
                </div>
              </template>
            </ElSkeleton>
          </ElCard>
        </div>

        <!-- 实际文件内容 -->
        <div
          v-if="!isLoading && filteredFiles.length > 0"
          class="grid gap-4 md:grid-cols-1 lg:grid-cols-1 xl:grid-cols-2"
        >
          <ElCard
            v-for="file in filteredFiles"
            :key="file.id"
            shadow="hover"
            class="cursor-pointer p-3 shadow-lg"
            :body-style="{ padding: '4px' }"
            @click="getResourceInfo(file)"
          >
            <div class="flex justify-between">
              <div class="flex flex-col space-y-2">
                <span class="text-base font-bold text-blue-500">
                  {{ file.name }}
                </span>
                <div
                  class="flex items-center space-x-2 text-sm text-gray-500 dark:text-amber-50"
                >
                  <img :src="imageSrc(file.type)" class="h-8 w-8" />
                  <p>{{ file.type }}</p>
                  <ElDivider direction="vertical" />
                  <span class="font-xs">发布时间：</span>
                  <time class="font-xs italic">{{ file.publishTime }}</time>
                </div>
              </div>
            </div>

            <!-- 操作按钮 -->
            <div class="mt-5 flex justify-between border-t pt-2 text-sm">
              <div class="flex items-center space-x-2">
                <span>发布者：</span>
                <ElAvatar
                  :title="adminInfo.userName"
                  :src="adminInfo.avatar ? adminInfo.avatar : avatar"
                  :size="25"
                  class="cursor-pointer hover:scale-110"
                />
                <span class="cursor-pointer text-blue-500">{{
                  adminInfo.userName
                }}</span>
              </div>
              <div class="flex space-x-2">
                <ElTooltip content="导入" placement="top">
                  <ElButton
                    circle
                    size="small"
                    type="success"
                    :icon="ElDocumentAdd"
                    @click="handleConfirm(file)"
                  />
                </ElTooltip>
                <ElTooltip content="发布" placement="top">
                  <ElButton
                    v-if="file.name.toLowerCase().endsWith('.geojson')"
                    circle
                    size="small"
                    :icon="ElUploadFilled"
                    @click="showPublishDialog(file.id, file.name, file.type)"
                  />
                </ElTooltip>
                <ElTooltip content="下载" placement="top">
                  <ElButton
                    circle
                    size="small"
                    type="primary"
                    :icon="ElDownload"
                    @click="downloadFile(file.fileId, file.url)"
                  />
                </ElTooltip>
                <ElTooltip content="查看" placement="top">
                  <ElButton
                    circle
                    size="small"
                    type="warning"
                    :icon="ElView"
                    @click="previewData(file)"
                  />
                </ElTooltip>
                <ElTooltip content="打标签" placement="top">
                  <ElButton
                    circle
                    size="small"
                    type="danger"
                    :icon="ElPriceTag"
                    @click="addTags(file.id, file.name)"
                  />
                </ElTooltip>
                <ElTooltip content="删除" placement="top" v-if="isAdmini">
                  <ElButton
                    circle
                    size="small"
                    type="danger"
                    :icon="ElDelete"
                    @click="deletePublic(file.id)"
                  />
                </ElTooltip>
              </div>
            </div>
          </ElCard>
        </div>

        <!-- 无数据提示 -->
        <ElEmpty
          class="flex h-full items-center justify-center"
          v-if="!isLoading && filteredFiles.length === 0"
          description="暂无文件"
        />

        <!-- 分页 -->
        <div
          v-if="filteredFiles.length > 0"
          class="col-span-2 mt-4 flex justify-center"
        >
          <ElPagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            layout="total, prev, pager, next, jumper"
            :total="total"
            background
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </div>

    <!-- 预览对话框 -->
    <MvtPreviewDialog
      v-if="isMvtPreviewDialogShow"
      :is-dialog-show="isMvtPreviewDialogShow"
      :current-mvt-data="currentSelectedFile"
      @close-preview-dialog="handleClosePreviewDialog"
      @show-preview-dialog="previewData"
    />
    <RasterPreviewDialog
      v-if="isRasterPreviewDialogShow"
      :is-dialog-show="isRasterPreviewDialogShow"
      :current-mvt-data="currentSelectedFile"
      @close-preview-dialog="handleClosePreviewDialogR"
      @show-preview-dialog="previewData"
    />
    <PublishDialog
      :is-publish-dialog-show="publishDialog"
      :current-selected-data="realSelectedFileData"
      :is-public="true"
      @close-publish-dialog="publishDialog = false"
      v-if="publishDialog"
    />
    <!-- 打标签 -->
    <AddTagDialog
      v-model="isAddTagShow"
      v-if="isAddTagShow"
      :is-add-tag-show="isAddTagShow"
      :data-id="tagFileId"
      :data-name="tagFileName"
      @close-add-tag-dialog="handleCloseDialog"
    />
  </Page>
</template>
